<template>
  <view class="xl-dropdown">
    <view :class="['xl-dropdown-items', border && 'xl-dropdown-items_border', shadow && 'xl-dropdown-items_shadow']">
      <view v-for="(item, index) in items" :key="index" class="xl-dropdown-item" :style="{height: $xl.parseUnit(height, 'rpx')}" @tap.stop="clickItem(item, index)">
        <view class="xl-dropdown-item_text" :style="{fontSize: $xl.parseUnit(fontSize, 'px'), color: cur === index ? color : '#888'}"> {{item.label}} </view>
        <xl-icon v-if="item.type !== 'click'" :name="cur === index ? 'xl-up-fill' : 'xl-down-fill'" :color="cur === index ? color : '#888'" size="13" left="5"></xl-icon>
      </view>
    </view>
    <xl-mask v-if="curItem?.type !== 'click'" :modelValue="cur !== -1" enterMode="fade-down" leaveMode="fade-down" :top="maskTop" @click="cur = -1">
      <scroll-view scroll-y class="xl-dropdown-scroll-view">
        <view v-if="curItem" class="xl-dropdown-content" :style="{padding: $xl.parseUnit(padding, 'rpx'), '--capsule-color': capsuleColor}">
          <view v-if="curItem.type==='group' && curItem.children" class="xl-dropdown-content__group">
            <view v-for="(item, index) in curItem.children" :key="index" class="xl-dropdown-content__group-item">
              <view class="group-item-label">{{item.label}}</view>
              <view v-if="item.type && item.type==='column'" class="xl-dropdown-content__column" style="margin-left: 6rpx;">
                <view v-for="(option, index) in item.options" :key="index" class="xl-dropdown-content__column-item" @click="chooseItem(item, index, true)">
                  <view class="item-text" :style="{color: option.checked ? color : '#666'}">{{option.label}}</view>
                  <xl-icon v-if="option.checked" name="xl-yes" :color="color" size="16"></xl-icon>
                </view>
              </view>
              <view v-else class="xl-dropdown-content__capsule">
                <view v-for="(option, index) in item.options" :key="index" @click="chooseItem(item, index, true)"
                      :class="['xl-dropdown-content__capsule-item', option.checked && 'capsule-item-checked']">
                  <view class="item-text">{{option.label}}</view>
                </view>
              </view>
            </view>
            <view class="xl-dropdown-content__button">
              <view class="button-text" @click="reset">重置</view>
              <view class="button-text" @click="confirm">确定</view>
            </view>
          </view>
          <view v-else-if="curItem.type==='column'" class="xl-dropdown-content__column">
            <view v-for="(option, index) in curItem.options" :key="index"  class="xl-dropdown-content__column-item" @click="chooseItem(curItem, index)">
              <view class="item-text" :style="{color: option.checked ? color : '#666'}">{{option.label}}</view>
              <xl-icon v-if="option.checked" name="xl-yes" :color="color" size="16"></xl-icon>
            </view>
          </view>
          <view v-else-if="curItem.type==='capsule'" class="xl-dropdown-content__capsule">
            <view v-for="(option, index) in curItem.options" :key="index" @click="chooseItem(curItem, index)"
                  :class="['xl-dropdown-content__capsule-item', option.checked && 'capsule-item-checked']">
              <view class="item-text">{{option.label}}</view>
            </view>
          </view>
          <view v-else-if="curItem.type==='slot'" class="xl-dropdown-content__slot">
            <slot :item="curItem" :chooseItem="chooseItem" :changeResult="changeResult"/>
          </view>
          <view v-if="curItem.type!=='slot' && curItem.multiple" class="xl-dropdown-content__bottom">
            <view class="xl-dropdown-content__button">
              <view class="button-text" @click="reset">重置</view>
              <view class="button-text" @click="confirm">确定</view>
            </view>
          </view>
        </view>
      </scroll-view>
    </xl-mask>
  </view>
</template>

<script setup>
import { ref, watch, computed, onMounted, getCurrentInstance } from 'vue'
import propsData from './props.js'
const props = defineProps(propsData)
const emits = defineEmits(['change'])

// 遮罩开始位置，通过下拉框的位置计算出来
const maskTop = ref(0)
const instance = getCurrentInstance();
// 胶囊背景色
const capsuleColor = ref("#fff");

// 最终结果
let result = {}
onMounted(()=>{
  uni.createSelectorQuery().in(instance).select('.xl-dropdown-items').boundingClientRect((data) => {
    maskTop.value = uni.$xl.px2upx(Math.floor(data.bottom))
  }).exec();
  // 初始化默认选中值
  initCheck(props.items);
  capsuleColor.value = uni.$xl.color.colorToRgba(props.color, 0.08);
})

function initCheck(items){
  items.forEach(item => {
    if (item.options) {
      const values = Array.isArray(item.value) ? item.value : [item.value];
      item.options.forEach(option => {
        option.checked = values.includes(option.value);
      });
      // 注意不能直接等于values，否则result修改了，item.value也修改了
      result[item.name] = Array.isArray(item.value) ? [...item.value] : item.multiple ? [item.value] : item.value;
    } else if (item.children) {
      // 递归处理 children
      initCheck(item.children);
    }
  });
}

const cur = ref(-1)
const curItem = ref(null)
// 点击下拉框item
function clickItem(item, index){
  if(cur.value === index){
    cur.value = -1;
  }else{
    cur.value = index
    curItem.value = item
  }
  if(item.type === 'click') {
    props.items.forEach(item => {
      if(!item.options) result[item.name] = false
    })
    result[item.name] = cur.value !== -1
    emits('change', result)
  }
}

// 选择值
function chooseItem(item, index, children = false){
  if(item.multiple){
    item.options[index].checked = !item.options[index].checked
    // 处理结果
    if(item.options[index].checked) result[item.name].push(item.options[index].value)
    else result[item.name] = result[item.name].filter(value => value !== item.options[index].value);
  }else {
    if(!item.options[index].checked) {
      item.options.forEach(option => option.checked = false);
      item.options[index].checked = true
      result[item.name] = item.options[index].value
    }
    // 单选，并且不是多项选择项，则触发
    if(!children){
      emits('change', result)
      cur.value = -1;
    }
  }
}

// 修改该项的值
function changeResult(item, value){
  result[item.name] = value;
  emits('change', result)
  cur.value = -1;
}

function reset(){
  initCheck([curItem.value])
}
function confirm(){
  emits('change', result)
  cur.value = -1;
}
</script>

<style lang="scss" scoped>
.xl-dropdown{
  .xl-dropdown-items{
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    width: 100%;
    justify-content: space-between;
    align-items: center;
    position: relative;
    z-index: 9999;
    background: v-bind(background);

    &.xl-dropdown-items_border{
      border-bottom: 1rpx solid #efefef;
    }

    &.xl-dropdown-items_shadow{
      box-shadow: 0 10rpx 16rpx 0 hsla(0, 0%, 60%, .05);
    }

    .xl-dropdown-item{
      /* #ifndef APP-NVUE */
      display: flex;
      /* #endif */
      flex-direction: row;
      justify-content: center;
      align-items: center;
      flex: 1;
    }
  }
  .xl-dropdown-scroll-view{
    position: relative;
    max-height: 1000rpx;
    .xl-dropdown-content{
      background: v-bind(background);
      &__column{
        &-item{
          height: 90rpx;
          /* #ifndef APP-NVUE */
          display: flex;
          /* #endif */
          flex-direction: row;
          justify-content: space-between;
          align-items: center;
          border-bottom: 1rpx solid #efefef;
          &:last-child{
            border-bottom: none;
          }
          .item-text{
            font-size: 14px;
            color: #666;
          }
        }
      }
      &__capsule{
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: wrap;
        gap: 20rpx;
        padding: 32rpx 0 34rpx;
        &-item{
          padding: 10rpx 30rpx;
          border-radius: 50rpx;
          background: #f5f5f5;
          // border: 1rpx solid #f5f5f5;
          .item-text{
            font-size: 13px;
            color: #333333;
          }
          &.capsule-item-checked{
            background: var(--capsule-color);
            // border: 1rpx solid var(--capsule-color);
            .item-text{
              color: v-bind(color);
            }
          }
        }
      }
      &__group{
        padding: 30rpx 0 100rpx;
        &-item{
          margin-bottom: 20rpx;

          .group-item-label {
            font-size: 16px;
            color: #333;
            font-weight: bold;
          }

          &:last-child{
            margin-bottom: 0;
          }
        }
      }
      &__bottom{
        height: 100rpx;
      }
      &__button{
        padding: 20rpx 30rpx 20rpx;
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        box-sizing: border-box;
        background: v-bind(background);

        .button-text{
          flex: 1;
          border: 1rpx solid v-bind(color);
          height: 70rpx;
          line-height: 70rpx;
          text-align: center;
          font-size: 14px;
          &:first-child{
            border-top-left-radius: 50rpx;
            border-bottom-left-radius: 50rpx;
            color: v-bind(color);
          }
          &:last-child{
            border-top-right-radius: 50rpx;
            border-bottom-right-radius: 50rpx;
            color: #ffffff;
            background: v-bind(color);
          }
        }
      }
    }
  }
}
</style>